package com.loan.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.loan.entity.*;
import com.loan.exception.*;
import com.loan.mappers.*;
import com.loan.service.RepaymentMethodService;
import com.loan.service.RepaymentService;
import com.loan.vo.RepaymentVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.support.WebApplicationContextUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @ClassName: RepaymentServiceImpl
 * @Author: wYin
 * @Date: 2022/1/18 16:57
 */
@Service("repaymentService")
@SuppressWarnings("all")
public class RepaymentServiceImpl extends ServiceImpl<RepaymentMapper, Repayment> implements RepaymentService {
    @Autowired
    private RepaymentMapper repaymentMapper;

    @Autowired
    private ContractMapper contractMapper;

    @Autowired
    private RepaymentMethodMapper repaymentMethodMapper;

    @Autowired
    private EmpMapper empMapper;

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private UserMapper userMapper;

    /**
     * 传入数据：客户id、还款表id、合同id、还款方式id、是否支付罚金(y||n)
     * 根据传入的客户id和还款表id以及合同id进行用户还款信息的修改
     *      过程：检查当前用户还款时间是否逾期（逾期则相应的状态为y)-逾期则合同表中逾期次数+1（如果愿意交取罚息，则相应的逾期次数不增加）
     *      更新数据：是否逾期（比较约定还款时间和实际还款时间）、实际还款时间、还款方式、（如果逾期是否交取罚金，交取罚金则相应的逾期次数不+1）、修改合同表中剩余的还款金额（合同表欠款金额-支付金额）
     * @Param: [repayment]
     * @Return: boolean
     * @Author: wYin
     * @Date: 2022/1/18 21:01
     */
    @Override
    @Transactional
    public boolean repaymentUpdate(Repayment repayment) {
        //根据当前客户的id和合同表的id以及还款表id查询还款数据
        Repayment repayment1 = repaymentMapper.selectOne(new QueryWrapper<Repayment>().and(t -> t.eq("cus_id", repayment.getCusId()).eq("con_id",
                repayment.getConId()).eq("id", repayment.getId())));
        if(repayment1==null){
            throw new RepaymentException("未查询到当前还款信息");
        }
        //根据查询到的合同信息进行还款信息的完成
        //判断还款方式是否存在
        RepaymentMethod repaymentMethod = repaymentMethodMapper.selectById(repayment.getRepaymentMethodId());
        if(repaymentMethod==null){
            throw new RepaymentMethodException("不支持当前的支付方式,支付方式id不存在");
        }
        repayment1.setRepaymentMethodId(repayment.getRepaymentMethodId());//还款方式
//        设置是否逾期
        BigDecimal penaltyInterest = computeDayInterest(repayment1);//罚息
        if(BigDecimal.valueOf(0).compareTo(penaltyInterest)<=0){//没有罚息--未违期
            repayment1.setStatus("n");
        }else{
            repayment1.setStatus("y");//设置是否违期
            if("y".equals(repayment.getPenaltyStatus())){//判断愿意支付罚金
                repayment1.setPenaltyInterest(penaltyInterest);
            }else{
                //todo:合同表中违期次数进行+1
                //得到合同表中信息判断逾期次数，如果已经达到三次则终止这次的还款
                Contract contract = contractMapper.selectById(repayment1.getConId());
                if(contract.getFrequency()==3){
                    throw new ContractException("当前的逾期次数已达3次，此次必须缴纳违期罚金，否则我行将对你进行强制性的债款一次性偿追讨");
                }else{
                    contract.setFrequency(contract.getFrequency()+1);
                    contract.setDebt(contract.getDebt().subtract(repayment1.getMoney()));//剩余欠款
                    //执行违约次数添加
                    contractMapper.updateById(contract);
                }
            }
        }
        repayment1.setActualTime(new Date());//实际还款时间
        //执行还款表数据的更新
        int row = repaymentMapper.updateById(repayment1);
        if(row>0){
            return true;
        }
        return false;
    }

    /**
     * @Desc: 接收传入的业务员id和合同id查询指定的还款信息
     * @Param: [repayment]
     * @Return: java.util.List<com.loan.entity.Repayment>
     * @Author: wYin
     * @Date: 2022/1/22 17:56
     */
    @Override
    public List<Repayment> getAppointRepayment(Repayment repayment) {
        //判断业务员的合法性
        Emp emp = empMapper.selectById(repayment.getEmpId());
        if(emp==null){
            throw new EmpException("当前用户不存在");
        }
        Contract contract = contractMapper.selectById(repayment.getConId());
        if(contract==null){
            throw new ContractException("当前合同不存在");
        }
        if (contract.getEmpId()!=emp.getId()) {
            throw new ContractException("当前合同的业务员不匹配");
        }
        if ("n".equals(contract.getLoan())) {
            throw new ContractException("当前合同还未放款");
        }
//        根据业务员id和合同id查询还款信息
        List<Repayment> repayments = repaymentMapper.selectList(new QueryWrapper<Repayment>().and(t -> t.eq("emp_id", repayment.getEmpId()).eq("con_id",
                repayment.getConId())));
        return repayments;
    }
    /**
     * @Desc: 通过传入的还款id，以及客户id、合同编号得到合同信息、用户信息、以及违期罚息
     * @Param: [repayment]
     * @Return: com.loan.vo.RepaymentVO
     * @Author: wYin
     * @Date: 2022/1/23 17:11
     */
    @Override
    public RepaymentVO getRepaymentAllInfo(Repayment repayment) {
//        根据传入的验证合法
        Repayment repayment1 = repaymentMapper.selectById(repayment.getId());
        if(repayment1==null){
            throw new RepaymentException("没有当前还款信息");
        }
        if(repayment1.getConId()!=repayment.getConId()){
            throw new ContractException("当前还款信息与合同中信息不匹配");
        }
        if(repayment1.getCusId()!=repayment.getCusId()){
            throw new CustomerException("当前客户信息与还款信息中客户不匹配");
        }
        RepaymentVO repaymentVO = new RepaymentVO();
        //根据传入信息得到合同信息、用户信息，以及得到违期罚息的信息
        Contract contract = contractMapper.selectById(repayment.getConId());
        repaymentVO.setContract(contract);
        Customer customer = customerMapper.selectById(repayment.getCusId());
        User user = userMapper.selectById(customer.getUserId());
        repaymentVO.setUser(user);
        //得到罚息的信息
        BigDecimal penaltyInterest = computeDayInterest(repayment1);
        repaymentVO.setPenaltyInterest(penaltyInterest);
        return repaymentVO;
    }

    /**
     * @Desc: 传入还款信息，得到违期罚息
     * @Param: [repayment] 当前还款的信息
     * @Return: BigDecimal 违期罚息
     * @Author: wYin
     * @Date: 2022/1/19 15:30
     */
    public BigDecimal computeDayInterest(Repayment repayment){
        //得到当前的时间
        Date date  = new Date();
        SimpleDateFormat sim = new SimpleDateFormat("yyyyMMdd");
        int nowDate = Integer.valueOf(sim.format(date));//实际还款时间
        int time1 = Integer.valueOf(sim.format(repayment.getAppoTime()));//约定的还款时间
        int result = time1-nowDate;//得到违期天数
        if(result>0){
            return BigDecimal.valueOf(0);
        }
        //todo 超过了约定的还款时间，已经逾期，计算罚金--根据利息的5%/天
        BigDecimal dayInterest = repayment.getInterest().divide(BigDecimal.valueOf(2), 2, BigDecimal.ROUND_HALF_UP);
        return dayInterest.multiply(BigDecimal.valueOf(result)).setScale(2, BigDecimal.ROUND_HALF_UP);
    }
}
